package com.cloudcentral.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;

/**
 * Create by Administrator
 * 2023/10/12 14:20
 */
@Slf4j
@Order(0)
@Component
public class GatewayFilter implements GlobalFilter {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    String clientIp = getClientIp(exchange.getRequest());
    exchange = exchange.mutate().request(builder -> builder.headers(headers -> headers.set("IP-Client", clientIp)).build()).build();
    return chain.filter(exchange);
  }

  private String getClientIp(ServerHttpRequest request) {
    HttpHeaders headers = request.getHeaders();
    String ip = headers.getFirst("X-Forwarded-For");
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
      ip = headers.getFirst("Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
      ip = headers.getFirst("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
      ip = headers.getFirst("X-Real-Ip");
    }
    if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
      ip = Optional.ofNullable(request.getRemoteAddress()).map(address -> address.getAddress().getHostAddress()).orElse("");
      if ("127.0.0.1".equals(ip) || "0:0:0:0:0:0:0:1".equals(ip)) {
        // 根据网卡取本机配置的IP
        try {
          InetAddress inet = InetAddress.getLocalHost();
          ip = inet.getHostAddress();
        } catch (UnknownHostException e) {
          log.error("IP获取异常", e);
        }
      }
    }
    // 对于通过多个代理的情况，第一个IP为客户端真实IP，多个IP按照','分割
    if (Objects.requireNonNull(ip).contains(",")) ip = Arrays.stream(ip.split(",")).filter(StringUtils::isNotBlank).toList().get(0);
    if (Objects.requireNonNull(ip).startsWith("/")) ip = ip.substring(1);
    return ip;
  }
}
